﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;
using BaMusaSoft.RPS.DataModel.Repositories;
using BaMusaSoft.RPS.RPSServices;
using BaMusaSoft.RPS.RPSServices.Reports;
using BaMusaSoft.RPS.ViewModel.Infrastructure;
using BaMusaSoft.RPS.ViewModel.Properties;
using GalaSoft.MvvmLight.Command;
using System.Collections.ObjectModel;
using BaMusaSoft.RPS.DataModel;
using System.Collections.Specialized;

namespace BaMusaSoft.RPS.ViewModel
{
    public class AllSchedulesViewModel : Workspace, IDataErrorInfo
    {
        #region "Fields"

        IUnitOfWork _unitOfWork;
        readonly SchedulesRepository _schedulesRepositroy;
        readonly ScheduleDetailsRepository _detailsRepository;
        RelayCommand _printCommand;
        RelayCommand _findCommand;
        ObservableCollection<AllSchedulesReportFields> _allSchedules;
        AllSchedulesSearchFields _searchFields;
        Settings _settings;
        Logger _logger;
        #endregion


        #region Constructor
        public AllSchedulesViewModel(IUnitOfWork unitOfWork)
        {
            if (unitOfWork == null) throw new ArgumentNullException("unitOfWork");
            _unitOfWork = unitOfWork;
            _schedulesRepositroy = _unitOfWork.Schedules as SchedulesRepository;
            _detailsRepository = _unitOfWork.ScheduleDetails as ScheduleDetailsRepository;
            DisplayName = Resources.AllSchedulesViewModel_DesplayName;
            _settings = Settings.Default;
            SearchFields = new AllSchedulesSearchFields();
            //OwnedWorkspaces.CollectionChanged += OnOwnedWorkspacesChanged;

        }

        


        #endregion
        #region "Binding Properties"

        public ObservableCollection<AllSchedulesReportFields> AllSchedules
        {
            get { return _allSchedules; }
            set
            {
                _allSchedules = value;
                RaisePropertyChanged("AllSchedules");
            }

        }
        public AllSchedulesSearchFields SearchFields
        {
            get { return _searchFields; }
            private set
            {
                _searchFields = value;
                RaisePropertyChanged("SearchFields");
            }
        }

        #endregion
        #region "Public Properties"
        public IUnitOfWork UnitOfWork
        {
            get { return _unitOfWork; }
        }

        #endregion
        #region "Commands"
        public ICommand FindCommand
        {
            get
            {
                if (_findCommand == null)
                {
                    _findCommand = new RelayCommand(Find);
                }
                return _findCommand;
            }
        }
        void Find()
        {
            var criteria = SearchFields.BuildCriteria();
            var data = LoadData();
            if (criteria != null)
            {
                data.Where(criteria.Compile());
            }
            AllSchedules = new ObservableCollection<AllSchedulesReportFields>(data);
        }


        public ICommand PrintCommand
        {
            get
            {
                if (_printCommand == null)
                {
                    _printCommand = new RelayCommand(Print);
                }
                return _printCommand;
            }

        }
        void Print()
        {
            //AllSchedulesReport report = new AllSchedulesReport(_settings.AllSchedulesExcelTemplatePath);
            //report.Build(AllSchedules);
            //report.Print();
            if (SelectedItem != null)
            {
                string scheduleId = SelectedItem.ScheduleId;
                MainViewModel.Current.EditScheduleCommnad.Execute(scheduleId);

            }
        }

        #endregion
        #region "Helper methods"
        private IList<AllSchedulesReportFields> LoadData()
        {
            var schedules = _schedulesRepositroy.GetAll();
            var details = _detailsRepository.GetAll();
            return (from schedule in schedules
                    join detail in details
                    on schedule.ScheduleId equals detail.ScheduleId
                    orderby schedule.Contract.PropertyNo
                    select new AllSchedulesReportFields
                    {
                        ScheduleId = schedule.ScheduleId,
                        RegistredAt = schedule.RegistredAt,
                        CustomerId = schedule.Contract.CustomerId,
                        CustomerName = schedule.Contract.Customer.Name,
                        ContractNo = schedule.ContractNo,
                        PropertyNo = schedule.Contract.PropertyNo,
                        PropertyDescription = schedule.Contract.Property.Description,
                        AmountDue = detail.AmountDue,
                        DateDue = detail.DateDue,
                        AmountPaid = detail.AmountPaid,
                        Balance = detail.Balance,
                        SignerName = schedule.Signer.Name,
                        Mobile = schedule.Signer.Mobile,
                        Phone = schedule.Signer.FirstPhone,
                        HadPaid = (detail.Balance == 0 ? true : false)
                    }).ToList();
        }

        #endregion

        #region Implementation of IDataErrorInfo

        /// <summary>
        /// Gets the error message for the property with the given name.
        /// </summary>
        /// <returns>
        /// The error message for the property. The default is an empty string ("").
        /// </returns>
        /// <param name="columnName">The name of the property whose error message to get. </param>
        public string this[string columnName]
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// Gets an error message indicating what is wrong with this object.
        /// </summary>
        /// <returns>
        /// An error message indicating what is wrong with this object. The default is an empty string ("").
        /// </returns>
        public string Error
        {
            get { throw new NotImplementedException(); }
        }

        #endregion
        #region Overrides of Workspace

        public sealed override string DisplayName
        {
            get;
            protected set;
        }

        public override bool HasChanges
        {
            get { return false; }
        }
        public override void Cleanup()
        {
            base.Cleanup();
        }
        #endregion

        #region "Public Methods"
        public Schedule GetSelectedSchedule(string scheduleId)
        {
            return _schedulesRepositroy.GetById(scheduleId);
        }
        #endregion

        public AllSchedulesReportFields SelectedItem { get; set; }

    }

}